﻿using CNative.WebApi.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using CNative.WebApi.Utils;
//using Microsoft.Owin;

namespace CNative.WebApi.Common
{
    /// <summary>
    /// 拦截器
    /// </summary>
    public class MyActionFilter : ActionFilterAttribute
    {
        #region 变量
        private Dictionary<string, string> _dictActionDesc = ServiceHelper.Get<Dictionary<string, string>>(() => XmlUtil.GetActionDesc());
        #endregion

        #region OnActionExecuting 执行方法前
        /// <summary>
        /// 执行方法前
        /// </summary>
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            base.OnActionExecuting(actionContext);

            //token验证
            Collection<AllowAnonymousAttribute> attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>();
            if (attributes.Count == 0)
            {
                IEnumerable<string> value;
                if (actionContext.Request.Headers.TryGetValues("token", out value))
                {
                    string token = value.ToArray()[0];

                    if (false) //todo:token验证
                    {
                        actionContext.Response = ApiHelper.ToJson(new JsonResult("token不匹配或已过期", ResultCode.token不匹配或已过期));
                        return;
                    }
                }
                else
                {
                    actionContext.Response = ApiHelper.ToJson(new JsonResult("请求头中不存在token", ResultCode.请求头中不存在token));
                    return;
                }
            }

            //post参数验证
            if (actionContext.Request.Method == HttpMethod.Post)
            {
                foreach (string key in actionContext.ActionArguments.Keys)
                {
                    object value = actionContext.ActionArguments[key];
                    if (value != null)
                    {
                        if (value.GetType().GetCustomAttributes(typeof(MyValidateAttribute), false).Length > 0)
                        {
                            string errMsg = null;
                            if (!ValidatePropertyUtil.Validate(value, out errMsg))
                            {
                                JsonResult jsonResult = new JsonResult(errMsg, ResultCode.参数不正确);
                                actionContext.Response = ApiHelper.ToJson(jsonResult);
                                return;
                            }
                        }
                    }
                }
            }

            //get参数验证
            if (actionContext.Request.Method == HttpMethod.Get)
            {
                foreach (string key in actionContext.ActionArguments.Keys)
                {
                    object value = actionContext.ActionArguments[key];
                    if (value != null)
                    {
                        if (key == "page")
                        {
                            if ((int)value <= 0)
                            {
                                JsonResult jsonResult = new JsonResult("page必须大于0", ResultCode.参数不正确);
                                actionContext.Response = ApiHelper.ToJson(jsonResult);
                                return;
                            }
                        }

                        if (key == "pageSize")
                        {
                            if ((int)value > 10000)
                            {
                                JsonResult jsonResult = new JsonResult("pageSize大于10000，请分页查询", ResultCode.参数不正确);
                                actionContext.Response = ApiHelper.ToJson(jsonResult);
                                return;
                            }
                        }
                    }
                }
            }
        }
        #endregion

        #region OnActionExecutedAsync 执行方法后
        /// <summary>
        /// 执行方法后
        /// </summary>
        public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
        {
            return Task.Factory.StartNew(async () =>
            {
                try
                {
                    Type controllerType = actionExecutedContext.ActionContext.ControllerContext.Controller.GetType();
                    MethodInfo methodInfo = controllerType.GetMethod(actionExecutedContext.ActionContext.ActionDescriptor.ActionName);

                    string action = controllerType.FullName + "." + methodInfo.Name;

                    if (_dictActionDesc.ContainsKey(action))
                    {
                        string jsonResult = null;
                        List<string> paramList = new List<string>();
                        string param = string.Empty;
                        if (actionExecutedContext.Request.Method == HttpMethod.Post)
                        {
                            foreach (string key in actionExecutedContext.ActionContext.ActionArguments.Keys)
                            {
                                object value = actionExecutedContext.ActionContext.ActionArguments[key];
                                if (value != null && value as HttpRequestMessage == null)
                                {
                                    paramList.Add(JsonConvert.SerializeObject(value));
                                }
                            }
                            param = string.Join(",", paramList);

                            if (actionExecutedContext.Exception == null)
                            {
                                byte[] bArr = await actionExecutedContext.ActionContext.Response.Content.ReadAsByteArrayAsync();
                                jsonResult = Encoding.UTF8.GetString(bArr);
                            }
                            else
                            {
                                JsonResult jr = new JsonResult(actionExecutedContext.Exception.Message + "\r\n" + actionExecutedContext.Exception.StackTrace, ResultCode.服务器内部错误);
                                jsonResult = JsonConvert.SerializeObject(jr);
                            }
                        }
                        else
                        {
                            foreach (string key in actionExecutedContext.ActionContext.ActionArguments.Keys)
                            {
                                object value = actionExecutedContext.ActionContext.ActionArguments[key];
                                if (value != null)
                                {
                                    paramList.Add(key + "=" + value.ToString());
                                }
                                else
                                {
                                    paramList.Add(key + "=");
                                }
                            }
                            param = string.Join("&", paramList);

                            if (actionExecutedContext.Exception == null)
                            {
                                if (actionExecutedContext.ActionContext.Response.Content is StringContent)
                                {
                                    byte[] bArr = await actionExecutedContext.ActionContext.Response.Content.ReadAsByteArrayAsync();
                                    jsonResult = Encoding.UTF8.GetString(bArr);
                                }
                                else
                                {
                                    jsonResult = JsonConvert.SerializeObject(new JsonResult<object>(null));
                                }
                            }
                            else
                            {
                                JsonResult jr = new JsonResult(actionExecutedContext.Exception.Message + "\r\n" + actionExecutedContext.Exception.StackTrace, ResultCode.服务器内部错误);
                                jsonResult = JsonConvert.SerializeObject(jr);
                            }
                        }

                        //string ip = null;
                        //if (actionExecutedContext.Request.Properties.ContainsKey("MS_OwinContext"))
                        //{
                        //    OwinContext owinContext = actionExecutedContext.Request.Properties["MS_OwinContext"] as OwinContext;
                        //    if (owinContext != null)
                        //    {
                        //        try
                        //        {
                        //            ip = owinContext.Request.RemoteIpAddress;
                        //        }
                        //        catch { }
                        //    }
                        //}

                        //todo:写操作日志
                        /*
                        ServiceHelper.Get<SysOperLogDal>().Log(action, //方法名
                            actionExecutedContext.Request.Method, //请求类型
                            _dictActionDesc[action], //方法注释
                            ip, //IP
                            actionExecutedContext.Request.RequestUri.LocalPath, //URL
                            param, //请求参数
                            jsonResult); //操作结果
                        */
                    }
                }
                catch (Exception ex)
                {
                    await LogUtil.Error(ex, "MyActionFilter OnActionExecutedAsync 写操作日志出错");
                }
            });
        }
        #endregion

    }
}